package cn.t.config;

import cn.t.core.mode.BaseDO;
import cn.t.facade.user.UserSessionFacade;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.EnableAspectJAutoProxy;
import org.springframework.stereotype.Component;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;

import javax.annotation.PostConstruct;
import java.lang.reflect.Field;
import java.util.Collection;
import java.util.Date;

/**
 * @author l
 */
@Configuration
@EnableAspectJAutoProxy
@Aspect
@Component
@Slf4j
public class RepositoryOperatorAspect {

    @PostConstruct
    public void init() {
        log.info("from RepositoryOperatorAspect ********** ");
    }

    @Before("execution(* cn.t..*.*RepositoryImpl.add*(..)) || execution(* cn.t..*.*RepositoryImpl.update*(..)) || execution(* cn.t..*.*RepositoryImpl.remove*(..)) || execution(* cn.t..*.*RepositoryImpl.del*(..))")
    public void beforeAddOrUpdateMethod(JoinPoint joinPoint) {
        // 在add或update方法执行前的操作，例如打印日志
        log.debug("Executing: " + joinPoint.getSignature().getName() + " (Operation: Add/Update)");

        Object[] args = joinPoint.getArgs();
        if (args == null || args.length == 0) {
            return;
        }

        boolean isAdd = joinPoint.getSignature().getName().contains("add");
        boolean isUpdate = joinPoint.getSignature().getName().contains("update") || joinPoint.getSignature().getName().contains("remove") || joinPoint.getSignature().getName().contains("del");
        ;
        for (Object arg : args) {
            appendOperator(arg, isAdd, isUpdate);
            trimString(arg);
        }
    }

    private void trimString(Object obj) {
        if (obj == null){
            return;
        }
        try {
            // 获取对象的类
            Class<?> clazz = obj.getClass();
            // 获取类的所有声明字段
            Field[] fields = clazz.getDeclaredFields();

            for (Field field : fields) {
                // 设置字段可访问，以便能够修改私有字段
                field.setAccessible(true);
                // 获取字段的值
                Object value = field.get(obj);
                // 检查字段是否为String类型
                if (value instanceof String) {
                    // 如果值不为null且是String类型，则去除首尾空格
                    String trimmedValue = ((String) value).trim();
                    // 将去空格后的值设置回字段
                    field.set(obj, trimmedValue);
                } else if (value instanceof Collection) {
                    for (Object item : (Collection<?>) value) {
                        trimString(item);
                    }
                }
            }
        } catch (IllegalAccessException e) {
            log.warn("trim string error:", e);
        }

    }


    private void appendOperator(Object arg, boolean isAdd, boolean isUpdate) {
        if (arg instanceof BaseDO) {
          //  String operator = userSessionFacade.getSession() != null ? userSessionFacade.getSession().operatorInfo() : "system";
          String operator = userSessionFacade.getSession() != null ? userSessionFacade.getSession().operatorInfo() :null;
            Date now = new Date();
            boolean notNullSession = !ObjectUtils.isEmpty(operator);
            if (isAdd) {
                if (!StringUtils.hasText(((BaseDO) arg).getCreator()) && notNullSession) {
                    ((BaseDO) arg).setCreator(operator);
                }
                if (!StringUtils.hasText(((BaseDO) arg).getModifier()) && notNullSession) {
                    ((BaseDO) arg).setModifier(operator);
                }

                if (((BaseDO) arg).getGmtCreated() == null) {
                    ((BaseDO) arg).setGmtCreated(now);
                }
                ((BaseDO) arg).setGmtModified(now);
                //创建人修改人必填
                if (!StringUtils.hasText( ((BaseDO) arg).getCreator())){
                    ((BaseDO) arg).setCreator("system-1");
                }
            } else if (isUpdate) {
                if (notNullSession){
                    ((BaseDO) arg).setModifier(operator);
                }
                ((BaseDO) arg).setGmtModified(now);
            }
            if (!StringUtils.hasText( ((BaseDO) arg).getModifier())){
                ((BaseDO) arg).setModifier("system-1");
            }
        } else if (arg instanceof Collection) {
            Collection<?> collection = (Collection<?>) arg;
            for (Object item : collection) {
                appendOperator(item, isAdd, isUpdate);
            }
        }
    }

    @Autowired
    private UserSessionFacade userSessionFacade;
}
